
class Saucier extends FFWeapon;

#exec MESH IMPORT MESH=SaucierAnimated3 ANIVFILE=MODELS\SaucierAnimated3_a.3d DATAFILE=MODELS\SaucierAnimated3_d.3d X=0 Y=0 Z=0 UnMirror=1
#exec MESH ORIGIN MESH=SaucierAnimated3 X=-200 Y=50 Z=0 YAW=64 PITCH=0 ROLL=0
#exec MESH LODPARAMS MESH=SaucierAnimated3 STRENGTH=0

/* Sequences are
1 Still
2-11 Shoot
12-17 Spray shooting
18-22 Go back in start position
23-42 Secondary "Blob"
43-89 Reload
90-98 Deselect
99-108 Select
*/

#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=All         STARTFRAME=0  NUMFRAMES=150
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Still       STARTFRAME=1  NUMFRAMES=1
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Shoot       STARTFRAME=2  NUMFRAMES=10
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Spray       STARTFRAME=12 NUMFRAMES=6
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=BackToStart STARTFRAME=18 NUMFRAMES=5
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Blob        STARTFRAME=23 NUMFRAMES=18
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Reload      STARTFRAME=43 NUMFRAMES=47
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Deselect    STARTFRAME=90 NUMFRAMES=9
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Down        STARTFRAME=90 NUMFRAMES=9
#exec MESH SEQUENCE MESH=SaucierAnimated3 SEQ=Select      STARTFRAME=99 NUMFRAMES=10

#exec TEXTURE IMPORT NAME=SaucierUVmap FILE=Textures/SaucierUVmap.bmp GROUP="Skins" LODSET=2

#exec MESHMAP SETTEXTURE MESHMAP=SaucierAnimated3 NUM=1 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierAnimated3 NUM=2 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierAnimated3 NUM=3 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierAnimated3 NUM=4 TEXTURE=SaucierUVmap

#exec MESHMAP NEW MESHMAP=SaucierAnimated3 MESH=SaucierAnimated3
#exec MESHMAP SCALE MESHMAP=SaucierAnimated3 X=0.005 Y=0.005 Z=0.01

//Pickup
#exec MESH IMPORT MESH=SaucierPickUp ANIVFILE=MODELS\SaucierPickUp_a.3d DATAFILE=MODELS\SaucierPickUp_d.3d X=0 Y=0 Z=0 UnMirror=1
#exec MESH ORIGIN MESH=SaucierPickUp X=0 Y=300 Z=-50 YAW=64 PITCH=0 ROLL=0

#exec MESH SEQUENCE MESH=SaucierPickUp SEQ=All STARTFRAME=0 NUMFRAMES=1
#exec MESH SEQUENCE MESH=SaucierPickUp SEQ=Still STARTFRAME=0 NUMFRAMES=1

#exec MESHMAP NEW MESHMAP=SaucierPickUp MESH=SaucierPickUp
#exec MESHMAP SCALE MESHMAP=SaucierPickUp X=0.03125 Y=0.03125 Z=0.0625
#exec MESH LODPARAMS MESH=SaucierPickUp STRENGTH=0

#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=1 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=2 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=3 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=4 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=5 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=6 TEXTURE=SaucierUVmap
#exec MESHMAP SETTEXTURE MESHMAP=SaucierPickUp NUM=7 TEXTURE=SaucierUVmap

#exec AUDIO IMPORT FILE="Sounds\SaucierAltFire.Wav"     NAME=SaucierAltFire      GROUP="Saucier"
#exec AUDIO IMPORT FILE="Sounds\SaucierLoad.Wav"        NAME=SaucierLoad      GROUP="Saucier"
#exec AUDIO IMPORT FILE="Sounds\SaucierSwitch.Wav"      NAME=SaucierSwitch      GROUP="Saucier"


var float ChargeSize, Count;
var bool bBurst;
var float TapTime;
var() int HitDamage;

var float TimesShot;

simulated function PlayIdleAnim()
{
   if ( Mesh == PickupViewMesh )
      return;
   if ( (Owner != None) && (VSize(Owner.Velocity) > 10) )
      PlayAnim('Still', 1.0);  //walking animation added?
   else
      TweenAnim('Still', 1.0);
   Enable('AnimEnd');
}

function TraceFire( float Accuracy )
{
   local vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z;
   local actor Other;

   Owner.MakeNoise(Pawn(Owner).SoundDampening);
   GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
   StartTrace = Owner.Location + CalcDrawOffset() + FireOffset.Y * Y + FireOffset.Z * Z;
   EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000 + Accuracy * (FRand() - 0.5 ) * Z * 1000 ;
   AdjustedAim = pawn(owner).AdjustAim(1000000, StartTrace, 2.75*AimError, False, False);
   EndTrace += (10000 * vector(AdjustedAim));
   Other = Pawn(Owner).TraceShot(HitLocation,HitNormal,EndTrace,StartTrace);
   ProcessTraceHit(Other, HitLocation, HitNormal, vector(AdjustedAim),Y,Z);
}

function float RateSelf( out int bUseAltMode )
{
   local float EnemyDist;
   local bool bRetreating;
   local vector EnemyDir;

   if ( AmmoType.AmmoAmount <=0 )
      return -2;
   bUseAltMode = 0;
   if ( Pawn(Owner).Enemy == None )
      return AIRating;

   EnemyDir = Pawn(Owner).Enemy.Location - Owner.Location;
   EnemyDist = VSize(EnemyDir);
   if ( EnemyDist > 1400 )
      return 0;

   bRetreating = (((EnemyDir/EnemyDist) Dot Owner.Velocity) < -0.6);
   if ((EnemyDist > 600) && (EnemyDir.Z > -0.4 * EnemyDist))
   {
      if ( !bRetreating )
         return 0;

      return AIRating;
   }
   bUseAltMode = int(FRand() < 0.3);

   if (bRetreating || (EnemyDir.Z < -0.7 * EnemyDist))
      return (AIRating + 0.18);
   return AIRating;
}

function float SuggestAttackStyle()
{
   return -0.3;
}

function float SuggestDefenseStyle()
{
   return -0.4;
}

function AltFire( float Value )
{
   bPointing=True;
   if ( AmmoType == None )
   {
      GiveAmmo(Pawn(Owner));
   }
   if ( AmmoType.UseAmmo(1) )
   {
      GoToState('AltFiring');
      bCanClientFire = true;
      ClientAltFire(Value);
   }
}

simulated function bool ClientAltFire( float Value )
{
   local bool bResult;

   InstFlash = 0.0;
   bResult = Super.ClientAltFire(value);
   InstFlash = Default.InstFlash;
   return bResult;
}

function Projectile ProjectileFire(class<projectile> ProjClass, float ProjSpeed, bool bWarn)
{
   local Vector Start, X,Y,Z;

   Owner.MakeNoise(Pawn(Owner).SoundDampening);
   GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
   Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
   AdjustedAim = pawn(owner).AdjustToss(ProjSpeed, Start, 0, True, (bWarn || (FRand() < 0.4)));
   return Spawn(ProjClass,,, Start,AdjustedAim);
}

simulated function PlayFiring()
{
	TimesShot = TimesShot - 1;
	PlayOwnedSound(AltFireSound, SLOT_None, Pawn(Owner).SoundDampening*4.0);
	if ( PlayerPawn(Owner) != None )
		PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
   LoopAnim('Shoot', 3.30 + 0.30 * FireAdjust,0.05);   //Maybe Spray?
   If (TimesShot <= 0)
	{
		TimesShot = 30;
		PlayReloading();
	}
}

simulated function PlayAltFiring()
{
	TimesShot = TimesShot - 1;
   PlayOwnedSound(Sound'SaucierLoad', SLOT_Misc, 1.3*Pawn(Owner).SoundDampening);    //loading goop
   if ( PlayerPawn(Owner) != None )
		PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
   PlayAnim('Still',0.24,0.05);
   If (TimesShot <= 0)
	{
		TimesShot = 30;
		PlayReloading();
	}
}

simulated function PlayReloading()
{
	PlayOwnedSound(Sound'PNutReload', SLOT_None,2.0*Pawn(Owner).SoundDampening);
	PlayAnim('Reload',0.5,0.05);
	Gotostate('Reloading');
}

function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
{
   local int i;
   local PlayerPawn PlayerOwner;
   Local RedGelPuff GB;
   local int j;

   if (Other==None)
   {
      HitNormal = -X;
      HitLocation = Owner.Location + X*10000.0;
   }

   PlayerOwner = PlayerPawn(Owner);
   if ( PlayerOwner != None )
      PlayerOwner.ClientInstantFlash( -0.4, vect(450, 190, 650));
   SpawnEffect(HitLocation, Owner.Location + CalcDrawOffset() + (FireOffset.X + 20) * X + FireOffset.Y * Y + FireOffset.Z * Z);

   if (Other == Level)
	{
		Spawn(class'SaucierHitEffect',,,HitLocation+HitNormal, rotator(HitNormal));
	}
	else if ( (Other != self) && (Other != Owner) && (Other != None) )
      Other.TakeDamage(HitDamage, Pawn(Owner), HitLocation, 60000.0*X, MyDamageType);
}

function SpawnEffect(vector HitLocation, vector SmokeLocation)
{
   local SauceStream Smoke,shock;
   local Vector DVector;
   local int NumPoints;
   local rotator SmokeRotation;

   DVector = HitLocation - SmokeLocation;
   NumPoints = VSize(DVector)/135.0;
   if ( NumPoints < 1 )
      return;
   SmokeRotation = rotator(DVector);
   SmokeRotation.roll = Rand(65535);
   Smoke = Spawn(class'SauceStream',,,SmokeLocation,SmokeRotation);
   Smoke.MoveAmount = DVector/NumPoints;
   Smoke.NumPuffs = NumPoints - 1;
}

state ClientFiring
{
	simulated function bool ClientFire(float Value)
   {
      if ( Level.TimeSeconds - TapTime < 0.2 )
         return false;
      bForceFire = bForceFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
      return bForceFire;
   }

   simulated function bool ClientAltFire(float Value)
   {
      if ( Level.TimeSeconds - TapTime < 0.2 )
         return false;
      bForceAltFire = bForceAltFire || ( bCanClientFire && (Pawn(Owner) != None) && (AmmoType.AmmoAmount > 0) );
      return bForceAltFire;
   }

   simulated function AnimEnd()
   {
      local bool bForce, bForceAlt;

      bForce = bForceFire;
      bForceAlt = bForceAltFire;
      bForceFire = false;
      bForceAltFire = false;

      if ( bCanClientFire && (PlayerPawn(Owner) != None) && (AmmoType.AmmoAmount > 0) )
      {
         if ( bForce || (Pawn(Owner).bFire != 0) )
         {
            Global.ClientFire(0);
            return;
         }
         else if ( bForceAlt || (Pawn(Owner).bAltFire != 0) )
         {
            Global.ClientAltFire(0);
            return;
         }
      }
      Super.AnimEnd();
   }

   simulated function EndState()
   {
      bForceFire = false;
      bForceAltFire = false;
   }

   simulated function BeginState()
   {
      TapTime = Level.TimeSeconds;
      bForceFire = false;
      bForceAltFire = false;
   }
}

state ClientAltFiring
{
   simulated function Tick(float DeltaTime)
   {
      if ( bBurst )
         return;
      if ( !bCanClientFire || (Pawn(Owner) == None) )
         GotoState('');
      else if ( Pawn(Owner).bAltFire == 0 )
      {
         PlayAltBurst();
         bBurst = true;
      }
   }

   simulated function AnimEnd()
   {
      if ( bBurst )
      {
         bBurst = false;
         Super.AnimEnd();
      }
      else
         TweenAnim('Still', 0.5);
   }
}

state AltFiring
{
   ignores AnimEnd;

   function Tick( float DeltaTime )
   {
      if ( ChargeSize < 4.1 )
      {
         Count += DeltaTime;
         if ( (Count > 0.5) && AmmoType.UseAmmo(1) )
         {
            ChargeSize += Count;
            Count = 0;
            if ( (PlayerPawn(Owner) == None) && (FRand() < 0.2) )
               GoToState('ShootLoad');
         }
      }
      if( (pawn(Owner).bAltFire==0) )
         GoToState('ShootLoad');
   }

   function BeginState()
   {
      ChargeSize = 0.0;
      Count = 0.0;
   }

   function EndState()
   {
      ChargeSize = FMin(ChargeSize, 4.1);
   }

Begin:
   FinishAnim();
}

state ShootLoad
{
   function ForceFire()
   {
      bForceFire = true;
   }

   function ForceAltFire()
   {
      bForceAltFire = true;
   }

   function Fire(float F)
   {
   }

   function AltFire(float F)
   {
   }

   function Timer()
   {
      local rotator R;
      local vector start, X,Y,Z;

      GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
      R = Owner.Rotation;
      R.Yaw = R.Yaw + Rand(8000) - 4000;
      R.Pitch = R.Pitch + Rand(1000) - 500;
      Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
      Spawn(AltProjectileClass,,, Start,R);

      R = Owner.Rotation;
      R.Yaw = R.Yaw + Rand(8000) - 4000;
      R.Pitch = R.Pitch + Rand(1000) - 500;
      Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
      Spawn(AltProjectileClass,,, Start,R);
   }

   function AnimEnd()
   {
      Finish();
   }

   function BeginState()
   {
      Local Projectile Gel;

      Gel = ProjectileFire(AltProjectileClass, AltProjectileSpeed, bAltWarnTarget);
      Gel.DrawScale = 1.0 + 0.8 * ChargeSize;
      PlayAltBurst();
   }
Begin:
}

function Finish()
{
   local bool bForce, bForceAlt;

   bForce = bForceFire;
   bForceAlt = bForceAltFire;
   bForceFire = false;
   bForceAltFire = false;

   if ( bChangeWeapon )
      GotoState('DownWeapon');
   else if ( PlayerPawn(Owner) == None )
   {
      Pawn(Owner).bAltFire = 0;
      Super.Finish();
   }
   else if ( (AmmoType.AmmoAmount<=0) || (Pawn(Owner).Weapon != self) )
      GotoState('Idle');
   else if ( (Pawn(Owner).bFire!=0) || bForce )
      Global.Fire(0);
   else if ( (Pawn(Owner).bAltFire!=0) || bForceAlt )
      Global.AltFire(0);
   else
      GotoState('Idle');
}

simulated function PlayAltBurst()
{
   if ( Owner.IsA('PlayerPawn') )
      PlayerPawn(Owner).ClientInstantFlash( InstFlash, InstFog);
   PlayOwnedSound(AltFireSound, SLOT_Misc, 1.7*Pawn(Owner).SoundDampening);   //shoot goop
   PlayAnim('Blob',1.4, 0.05);
}

simulated function PostRender(canvas C)
{
	local PlayerPawn P;
   local float Scale;
   local font CanvasFont;

   Super.PostRender(C);
   P = PlayerPawn(Owner);
   if ( (P != None) )
   {
		Scale = C.ClipX/640;
      C.SetPos(C.ClipX - 32 * Scale, C.ClipY - 192 * Scale);
      C.Style = ERenderStyle.STY_Translucent;
		C.DrawIcon(Texture'FFAmmoClip', Scale/2);
      C.Font = C.LargeFont;
		C.SetPos(C.ClipX - 22 * Scale, C.ClipY - 180 * Scale);
		C.DrawText(int(TimesShot), false);
	}
}


defaultproperties
{
	hitdamage=5
	bInstantHit=True
   InstFlash=-0.15
   InstFog=(X=139.00000,Y=218.00000,Z=72.00000)
   AmmoName=Class'Botpack.bioammo'
   PickupAmmoCount=75
   bAltWarnTarget=True
   bRapidFire=True
   FiringSpeed=1.000000
   FireOffset=(X=12.000000,Y=-11.000000,Z=-6.000000)
   AltProjectileClass=Class'RedGlobBig'
   AIRating=0.600000
   RefireRate=0.900000
   AltRefireRate=0.700000
   FireSound=Sound'UnrealI.BioRifle.GelShot'
   AltFireSound=SaucierAltFire
   CockingSound=SaucierLoad
   SelectSound=SaucierSwitch
   DeathMessage="%o drank a glass of %k's red hot load."
   AutoSwitchPriority=3
   InventoryGroup=3
   PickupMessage="You got the Saucier."
   ItemName="Saucier"
   PlayerViewOffset=(X=1.700000,Y=-0.850000,Z=-0.950000)
   PlayerViewMesh=SaucierAnimated3
   BobDamping=0.972000
   PickupViewMesh=SaucierPickUp
   ThirdPersonMesh=SaucierPickUp
   StatusIcon=Texture'Botpack.Icons.UseBio'
   PickupSound=Sound'UnrealShare.Pickups.WeaponPickup'
   Icon=Texture'Botpack.Icons.UseBio'
   Mesh=SaucierPickUp
   bNoSmooth=False
   CollisionRadius=30.000000
   CollisionHeight=19.000000
   WeaponDescription="Sprays hot sauce, igniting stuff and causing mayhem."
   NameColor=(R=0,G=255,B=0)
   ThirdPersonScale=0.50
   TimesShot=30
}
